import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { Object3D, Texture, TextureLoader, RepeatWrapping } from 'three';

const fbxLoader = new FBXLoader();
const objLoader = new OBJLoader();

/**
 * 模型加载器配置映射
 */
type LoaderStrategy = {
  [ext: string]: {
    loader: FBXLoader | OBJLoader;
    readAsFunction: 'readAsArrayBuffer' | 'readAsText';
  };
};

const loaderStrategy: LoaderStrategy = {
  '.fbx': {
    loader: fbxLoader,
    readAsFunction: 'readAsArrayBuffer',
  },
  '.obj': {
    loader: objLoader,
    readAsFunction: 'readAsText',
  },
};

/**
 * 加载纹理资源
 * @param url - 纹理URL
 * @returns 加载完成的纹理
 */
export function loadTexture(url: string): Promise<Texture> {
  return new Promise((resolve, reject) => {
    const loader = new TextureLoader();
    loader.load(
      url,
      (texture) => {
        texture.wrapS = RepeatWrapping;
        texture.wrapT = RepeatWrapping;
        resolve(texture);
      },
      undefined,
      (reason) => {
        reject(reason);
      }
    );
  });
}

/**
 * 通过URL加载FBX模型
 * @param url 模型URL
 * @param scale 缩放比例，默认为0.005
 * @returns 加载完成的3D对象
 */
export function loadFbxByUrl(url: string, scale = 0.005): Promise<Object3D> {
  return new Promise((resolve, reject) => {
    fbxLoader.load(
      url,
      (object3d) => {
        object3d.scale.set(scale, scale, scale);
        console.log('Fbx模型加载', object3d);
        resolve(object3d);
      },
      undefined,
      (error) => {
        reject(error);
      }
    );
  });
}

/**
 * 通过URL加载OBJ模型
 * @param url 模型URL
 * @returns 加载完成的3D对象
 */
export function loadObj(url: string): Promise<Object3D> {
  return new Promise((resolve, reject) => {
    objLoader.load(
      url,
      (object3d) => {
        const scale = 0.8;
        object3d.scale.set(scale, scale, scale);
        console.log('Obj模型加载', object3d);
        resolve(object3d);
      },
      undefined,
      (error) => {
        reject(error);
      }
    );
  });
}

/**
 * 根据URL自动判断类型加载模型
 * @param url 模型URL
 * @param scale 缩放比例，默认为1
 * @returns 加载完成的3D对象
 */
export function loadByUrl(url: string, scale = 1): Promise<Object3D> {
  const urlExtension = url.slice(url.lastIndexOf('.'));
  const { loader } = loaderStrategy[urlExtension] || {};

  if (!loader) {
    return Promise.reject(new Error(`不支持的文件类型: ${urlExtension}`));
  }

  return new Promise((resolve, reject) => {
    loader.load(
      url,
      (object3d) => {
        object3d.scale.set(scale, scale, scale);
        console.log('[loader] URL模型加载', object3d);
        resolve(object3d);
      },
      undefined,
      (error) => {
        reject(error);
      }
    );
  });
}

// /**
//  * 通过文件对象加载模型
//  * @param file 模型文件
//  * @param scale 缩放比例，默认为0.005
//  * @returns 加载完成的3D对象
//  */
// export function loadByFile(file: File, scale = 0.005): Promise<Object3D> {
//   return new Promise((resolve, reject) => {
//     if (!file) {
//       return reject(new Error('未提供文件'));
//     }

//     const fileExtension = file.name.slice(file.name.lastIndexOf('.'));
//     const strategy = loaderStrategy[fileExtension];

//     if (!strategy) {
//       return reject(new Error(`不支持的文件类型: ${fileExtension}`));
//     }

//     const { loader, readAsFunction } = strategy;
//     const reader = new FileReader();

//     reader.onload = function (e: ProgressEvent<FileReader>) {
//       const readResults = e.target?.result;
//       const object3d = loader.parse(readResults,);
//       object3d.scale.set(scale, scale, scale);
//       console.log('[file]模型加载', object3d);
//       resolve(object3d);
//     };

//     reader.onerror = function () {
//       reject(new Error(`文件读取错误: ${reader.error?.message}`));
//     };

//     reader[readAsFunction](file);
//   });
// }
